#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "Util.hpp"
const std::string sep = "\r\n";
const std::string default_root = "./wwwroot";      // web根目录
const std::string home_page = "index.html";        // 默认首页页面
const std::string html_404 = "./wwwroot/404.html"; // 访问错误资源的页面

// 服务端的请求与响应
class HttpRequest
{
public:
    HttpRequest() {}
    ~HttpRequest() {}

    // 解析来自浏览器的请求报文
    void prase()
    {
        // 1.从inbuffer中拿取第一行,分隔符\r\n
        std::string line = Util::getOneline(inbuffer, sep);
        if (line.empty())
            return;
        // 2.从请求行中提取三个字段 请求的 url 和http版本
        std::stringstream ss(line);
        ss >> method >> url >> httpversion;
        // 2. /a/b/c/s?name=zhangsan&pwd=12345
        // 可以通过？将？左右的字符串分离   如果是POST，本身就是分离的
        // ?左边就是path    右边是数据

        // 3.添加web的默认路径
        path = default_root;
        path += url; // url默认是/ 或者是传入传递的 /a/b/c  通过定义默认路径 -> ./wwwroot/aa/b/c
        if (path[path.size() - 1] == '/')
        {
            path = default_root;
            path += "/";
            path += home_page;
        }

        // 4.获取path对应资源的后缀
        // www.root/index.html  www/root/image.jpg
        auto pos = path.rfind(".");
        if (pos == std::string::npos)
            suffix = ".html";
        else
            suffix = path.substr(pos);

        // 5.得到资源的大小
        struct stat st;
        int n = stat(path.c_str(), &st);
        if (n == 0)
            size = st.st_size;
    }

public:
    std::string inbuffer; // 请求的所有数据
    // std::string reqline;                 // 请求行数据
    // std::vector<std::string> reqhandler; // 请求的报头,请求空行不要了
    // std::string body;                    // 请求正文

    std::string method;      // 请求行的方法
    std::string url;         // 请求行的网址
    std::string httpversion; // 请求行的http版本
    std::string path;        // 根据用户请求的url构成的path
    std::string suffix;      // 资源的后缀
    int size;
};

class HttResponse
{
public:
    std::string outbuffer;
};

const std::string suffixToDesc(const std::string suffix)
{
    std::string ct = "Content-Type: ";
    if (suffix == ".html")
        ct += "text/html";
    else if (suffix == ".png")
        ct += "image/png";
    else if (suffix == ".webp")
        ct += "image/webp";
    else if (suffix == ".jpg")
        ct += "image/jpeg";
    else if (suffix==".ico")
        ct += "image/x-icon";

    ct += "\r\n";
    return ct;
}
